home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / usenet / volume5 / puzzle15 < prev    next >
Encoding:
Internet Message Format  |  1988-08-30  |  7.2 KB

  1. Path: uunet!tektronix!tekgen!tekred!games
  2. From: games@tekred.TEK.COM
  3. Newsgroups: comp.sources.games
  4. Subject: v05i059:  puzzle15 - 15 square puzzle (get the numbers in sequence)
  5. Message-ID: <2989@tekred.TEK.COM>
  6. Date: 31 Aug 88 17:37:28 GMT
  7. Sender: billr@tekred.TEK.COM
  8. Lines: 258
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted by: "Peter Knoppers, Delft Univ. of Technology" <uunet.uu.net!mcvax!dutesta!knop>
  12. Comp.sources.games: Volume 5, Issue 59
  13. Archive-name: puzzle15
  14.  
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then unpack
  18. # it by saving it into a file and typing "sh file".  To overwrite existing
  19. # files, type "sh file -c".  You can also feed this as standard input via
  20. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  21. # will see the following message at the end:
  22. #        "End of shell archive."
  23. # Contents:  README Makefile puzzle15.c
  24. # Wrapped by billr@saab on Wed Aug 31 10:35:26 1988
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f 'README' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'README'\"
  28. else
  29. echo shar: Extracting \"'README'\" \(919 characters\)
  30. sed "s/^X//" >'README' <<'END_OF_FILE'
  31. XThis is a small program that plays the 15-puzzle game
  32. X(is that the correct name of this game ?), similar to the one
  33. Xin the desktop of some famous personal computers.
  34. X
  35. XThe size of the game can be set with an optional argument,
  36. Xdefault is 4, other sizes are 3, 5 and 6. Moves are made with
  37. Xthe 'h', 'j', 'k' and 'l' keys (like in vi). Any other key
  38. Xprints a diagnostic, your local interrupt key aborts the
  39. Xgame. When all pieces are sorted the program printes the
  40. Xnumber of moves that were used and exits.
  41. X
  42. XThe program is copyrighted to prevent creation and distribution of
  43. Xa zillion different versions and/or trojan horses. If you have
  44. Xsuggestions for improvements please mail them to me.
  45. X
  46. XWe compile the program by
  47. Xcc -O puzzle15.c -lcurses -ltermilb -o puzzle15
  48. X
  49. XEnjoy!
  50. X-- 
  51. XPeter Knoppers, Delft Univ. of Technology
  52. X.--. . - . .-.   -.- -. --- .--. .--. . .-. ... 
  53. X...!mcvax!dutrun!dutesta!knop
  54. X  or
  55. Xknop@dutesta.UUCP
  56. X
  57. END_OF_FILE
  58. if test 919 -ne `wc -c <'README'`; then
  59.     echo shar: \"'README'\" unpacked with wrong size!
  60. fi
  61. # end of 'README'
  62. fi
  63. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  64.   echo shar: Will not clobber existing file \"'Makefile'\"
  65. else
  66. echo shar: Extracting \"'Makefile'\" \(101 characters\)
  67. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  68. X# simple makefile for puzzle15
  69. Xpuzzle15: puzzle15.c
  70. X    cc -o puzzle15 -O puzzle15.c -lcurses -ltermcap
  71. END_OF_FILE
  72. if test 101 -ne `wc -c <'Makefile'`; then
  73.     echo shar: \"'Makefile'\" unpacked with wrong size!
  74. fi
  75. # end of 'Makefile'
  76. fi
  77. if test -f 'puzzle15.c' -a "${1}" != "-c" ; then 
  78.   echo shar: Will not clobber existing file \"'puzzle15.c'\"
  79. else
  80. echo shar: Extracting \"'puzzle15.c'\" \(4059 characters\)
  81. sed "s/^X//" >'puzzle15.c' <<'END_OF_FILE'
  82. X# include <curses.h>
  83. X# include <signal.h>
  84. X# define BLANK    0
  85. X# define UP    'k'
  86. X# define LEFT    'h'
  87. X# define DOWN    'j'
  88. X# define RIGHT    'l'
  89. X
  90. Xchar   *author = "(C) Copyright 1985, 1988 P. Knoppers";
  91. Xchar   *release1 = "Permission to use and redistribute unmodified ";
  92. Xchar   *release2 = "copies is granted to everyone";
  93. X
  94. Xchar   *malloc ();        /* to satisfy lint */
  95. X
  96. Xdie ()                /* nice exit on ctrl-C */
  97. X{
  98. X    signal (SIGINT, SIG_IGN);
  99. X    mvprintw (23, 0, "Goodbye. ");
  100. X    refresh ();
  101. X    endwin ();
  102. X    exit (0);
  103. X}
  104. X
  105. Xmain (argc, argv)        /* plays a simple game "15 puzzle" */
  106. Xchar  **argv;            /* with variations in boardsize... */
  107. X{
  108. X    register int    i, j;
  109. X    int     size = 4;        /* default size of the board */
  110. X    int     size2;
  111. X    int    *board;
  112. X    int     empty;        /* position of empty field */
  113. X    int     out;
  114. X    int     m;
  115. X    int     swap;
  116. X    int     nswap = 0;
  117. X    int     movecnt = 0;
  118. X    if (argc > 2)
  119. X    argerr (argv[0]);
  120. X    if (argc == 2)
  121. X    if (sscanf (argv[1], "%d", &size) < 1)
  122. X        argerr (argv[0]);
  123. X    if ((size < 3) || (size > 6))
  124. X    {
  125. X    fprintf (stderr, "size must be 3, 4, 5, or 6\n");
  126. X    exit (1);
  127. X    }
  128. X    size2 = size * size;    /* surface area of the board */
  129. X    board = (int *) malloc ((unsigned) size2 * sizeof (int));
  130. X    if (board == NULL)
  131. X    {
  132. X    fprintf (stderr, "%s: malloc failed\n", argv[0]);
  133. X    exit (1);
  134. X    }
  135. X
  136. X    srand (getpid ());        /* initialize random number generator */
  137. X    for (i = 1; i < size2; i++)    /* put pieces on the board */
  138. X    board[i - 1] = i;
  139. X    for (i = size2 - 2; i > 0; i--)/* permutate pieces */
  140. X    {
  141. X    j = rand () % i;
  142. X    swap = board[i];
  143. X    board[i] = board[j];
  144. X    board[j] = swap;
  145. X    }
  146. X    for (i = 0; i < size2 - 1; i++)/* is permutation a legal position ? */
  147. X    for (j = 0; j < i; j++)
  148. X        if (board[j] > board[i])
  149. X        nswap++;
  150. X    if (nswap % 2)
  151. X    {                /* illegal position, swap two pieces */
  152. X    swap = board[1];
  153. X    board[1] = board[0];
  154. X    board[0] = swap;
  155. X    }
  156. X    empty = size2 - 1;        /* empty field starts in lower right corner */
  157. X
  158. X    signal (SIGINT, die);
  159. X    initscr ();
  160. X    crmode ();
  161. X    noecho ();
  162. X
  163. X    while (1)            /* until final position is reached */
  164. X    {
  165. X    printboard (size, board);
  166. X    out = 1;
  167. X    for (i = 0; i < size2 - 1; i++)
  168. X        if (board[i] != i + 1)
  169. X        out = 0;
  170. X    if (out)
  171. X        break;        /* game ends */
  172. X    while (1)        /* until legal move is entered */
  173. X    {
  174. X        m = getch ();
  175. X        if ((m != LEFT) && (m != UP) && (m != RIGHT) &&
  176. X            (m != DOWN))
  177. X        {
  178. X        notmove ();
  179. X        continue;    /* not a move */
  180. X        }
  181. X        if (m == LEFT)
  182. X        if (empty % size)
  183. X        {
  184. X            board[empty] = board[empty - 1];
  185. X            board[empty - 1] = BLANK;
  186. X            empty--;
  187. X            movecnt++;
  188. X            break;
  189. X        }
  190. X        if (m == UP)
  191. X        if (empty >= size)
  192. X        {
  193. X            board[empty] = board[empty - size];
  194. X            board[empty - size] = BLANK;
  195. X            empty -= size;
  196. X            movecnt++;
  197. X            break;
  198. X        }
  199. X        if (m == RIGHT)
  200. X        if ((empty + 1) % size)
  201. X        {
  202. X            board[empty] = board[empty + 1];
  203. X            board[empty + 1] = BLANK;
  204. X            empty++;
  205. X            movecnt++;
  206. X            break;
  207. X        }
  208. X        if (m == DOWN)
  209. X        if (empty + size < size2)
  210. X        {
  211. X            board[empty] = board[empty + size];
  212. X            board[empty + size] = BLANK;
  213. X            empty += size;
  214. X            movecnt++;
  215. X            break;
  216. X        }
  217. X    }
  218. X    }
  219. X    mvprintw (22, 0, "You've reached the solution in %d moves.\n", movecnt);
  220. X    refresh ();
  221. X    endwin ();
  222. X}
  223. X
  224. Xargerr (s)
  225. Xchar   *s;
  226. X{
  227. X    fprintf (stderr, "usage: %s size\n", s);
  228. X    exit (1);
  229. X}
  230. X
  231. Xprintboard (size, board)
  232. Xint    *board;
  233. X{
  234. X    register int    i, j;
  235. X    mvprintw (0, 0, "|");    /* print top edge of board */
  236. X    for (j = 0; j < size; j++)
  237. X    printw ("----|");
  238. X    for (i = 0; i < size; i++)
  239. X    {
  240. X    mvprintw (i * 2 + 1, 0, "| ");
  241. X    for (j = 0; j < size; j++)
  242. X        if (board[size * i + j])
  243. X        printw ("%2d | ", board[size * i + j]);
  244. X        else
  245. X        printw ("   | ");
  246. X    mvprintw (i * 2 + 2, 0, "|");
  247. X    for (j = 0; j < size; j++)
  248. X        printw ("----|");
  249. X    }
  250. X    mvprintw (16, 0, "\n");    /* erase error messages */
  251. X    refresh ();            /* put all this on the screen */
  252. X}
  253. X
  254. Xnotmove ()
  255. X{
  256. X    mvprintw (16, 0,
  257. X        "use %c for up, %c for left, %c for right and %c for down",
  258. X        UP, LEFT, RIGHT, DOWN);
  259. X    refresh ();
  260. X}
  261. END_OF_FILE
  262. if test 4059 -ne `wc -c <'puzzle15.c'`; then
  263.     echo shar: \"'puzzle15.c'\" unpacked with wrong size!
  264. fi
  265. # end of 'puzzle15.c'
  266. fi
  267. echo shar: End of shell archive.
  268. exit 0
  269.